﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq.Expressions;
using System.Text;

namespace Dapper.Library
{
    public abstract class SqlProvider
    {
        public SetContext SetContext { get; set; }

        protected SqlProvider()
        {
            Params = new DynamicParameters();
            SetContext = new SetContext();
        }

        protected abstract SymbolInfo SymbolInfo { get; set; }

        public string SqlString { get; set; }

        public DynamicParameters Params { get; set; }
        /// <summary>
        /// 拼装单条查询SQL
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public abstract SqlProvider FormatToSingle<T>();

        /// <summary>
        /// 拼装多条查询SQL
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public abstract SqlProvider FormatToList<T>();

        /// <summary>
        /// 拼装分页查询SQL
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public abstract SqlProvider FormatToPageList<T>(int pageIndex, int pageSize);

        /// <summary>
        /// 获取COUNT()函数SQL
        /// </summary>
        /// <returns></returns>
        public abstract SqlProvider FormatCount();

        /// <summary>
        /// 获取Exists()函数SQL
        /// </summary>
        /// <returns></returns>
        public abstract SqlProvider FormatExists();

        /// <summary>
        /// 获取DeleteSQL
        /// </summary>
        /// <returns></returns>
        public abstract SqlProvider FormatDelete();


        /// <summary>
        /// 获取ExecuteNoQuerySQ
        /// </summary>
        /// <returns></returns>
        public abstract SqlProvider FormatExecuteNoQuery();
        

        /// <summary>
        /// 获取Insert-SQL
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public abstract SqlProvider FormatInsert<T>(T entity);

        /// <summary>
        /// 获取Update-SQL
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="updateExpression"></param>
        /// <returns></returns>
        public abstract SqlProvider FormatUpdate<T>(Expression<Func<T, T>> updateExpression);

        /// <summary>
        /// 获取Update-SQL
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public abstract SqlProvider FormatUpdate<T>(T entity);

        /// <summary>
        /// 获取Sum-SQL
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="lambdaExpression"></param>
        /// <returns></returns>
        public abstract SqlProvider FormatSum<T>(LambdaExpression lambdaExpression);

        /// <summary>
        ///  获取先Update-再Select-SQL
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="updator"></param>
        /// <returns></returns>
        public abstract SqlProvider FormatUpdateSelect<T>(Expression<Func<T, T>> updator);

        /// <summary>
        /// 获取批量插入-SQL
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="conn"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        public abstract SqlProvider ExcuteBulkCopy<T>(IDbConnection conn, IEnumerable<T> list);

        /// <summary>
        /// 拼装表名称
        /// </summary>
        /// <param name="isNeedFrom"></param>
        /// <returns></returns>
        protected string FormatTableName(bool isNeedFrom = true)
        {
            var typeOfTableClass = SetContext.TableType;

            var tableName = typeOfTableClass.GetTableAttributeName();

            SqlString = $" {SymbolInfo.CombineFieldName(tableName)} ";
            if (isNeedFrom)
                SqlString = " FROM " + SqlString;

            return SqlString;
        }

        /// <summary>
        /// 获取插入字段信息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        protected string[] FormatInsertParamsAndValues<T>(T entity)
        {
            var paramSqlBuilder = new StringBuilder(64);
            var valueSqlBuilder = new StringBuilder(64);

            var properties = entity.GetProperties();

            var isAppend = false;
            foreach (var propertiy in properties)
            {
                if (isAppend)
                {
                    paramSqlBuilder.Append(",");
                    valueSqlBuilder.Append(",");
                }

                var columnName = propertiy.GetColumnAttributeName();
                if (columnName.ToLower()!="id")
                {
                    var paramterName = SymbolInfo.ParameterPrefix + columnName;
                    paramSqlBuilder.Append(SymbolInfo.CombineFieldName(columnName));
                    valueSqlBuilder.Append(paramterName);

                    Params.Add(paramterName, propertiy.GetValue(entity));

                    isAppend = true;
                }
            }
            return new[] { paramSqlBuilder.ToString(), valueSqlBuilder.ToString() };
        }
    }
}
